home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIS Performer 2.2 Friends Demo
/
SGI IRIS Performer 2.2 Friends Demo.iso
/
friends
/
technology_playgroup
/
unwinder
/
driver_simple
/
read_dual.c
< prev
Wrap
C/C++ Source or Header
|
1997-11-17
|
8KB
|
283 lines
/**********************************************************************
* TECHNOLOGY PLAYGROUP INC. http://this.is/tpg email: tpg@this.is
**********************************************************************
*
* read_dual.c
*
* Version: 1.0
* Date: 17 november 1997
*
* Sample program to open the serial port, and poll data from the
* UNWINDER dual joystick adapter v2.1.
*
* This should get you started in writing a basic serial port driver,
* refer to the technical documentation for details on the data format,
* protocols, etc. This program only checks for a bad checksum, you
* should also be checking the Status and Mode byte bits.
*
*
**********************************************************************/
/**********************************************************
* New machines such as O2/Origin/Octane use a new termios
* data structure for IRIX 6.xx to support baud rates
* above 38400.
* To use the old termios - uncomment the next line
*********************************************************/
/* #define OLD_TERMIO */
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <errno.h> /* Error number definitions */
#include <termios.h> /* POSIX terminal control definitions */
const char* serial_port = "/dev/ttyd2";
/*************************************
* single joystick mode
*************************************/
/* const char* poll_cmd = "1"; */
/* int num_bytes = 11; */
/*************************************
* dual joystick mode
*************************************/
const char* poll_cmd = "3"; /* command to poll data */
int num_bytes = 19; /* number of bytes from UNWINDER */
int fd;
char in[1000];
char buffer[1000];
struct termio termio;
/********************************
* joystick data structure
*******************************/
typedef struct {
unsigned short x; /* X stick axis (left/down) */
unsigned short y; /* Y stick axis (up/down) */
unsigned short z; /* Z stick axis (rotation) */
unsigned short t; /* T stick axis (slider) */
unsigned char buttons; /* all buttons switch status */
unsigned char hat; /* hat position */
unsigned char sw; /* switch on or off (digital mode only) */
} joystick;
/********************************
* setup serial port termios
*******************************/
open_port(void)
{
fd = open(serial_port, O_RDWR, 0666 );
if (fd == -1)
{
printf("open %s - failed with error %s\n",serial_port,strerror(errno));
return 0;
}
/* see man page for 'termio' -- for serial port setup */
ioctl(fd, TCGETA, &termio );
termio.c_iflag = 0;
termio.c_oflag = 0;
#ifdef OLD_TERMIO
termio.c_cflag = B9600 | CS8 | CREAD | CLOCAL;
#else
termio.c_cflag = CS8 | CREAD | CLOCAL;
termio.c_ispeed = B9600;
termio.c_ospeed = B9600;
#endif
termio.c_lflag = 0;
termio.c_line = 0;
termio.c_cc[0] = 0;
termio.c_cc[VMIN] = 0; /* non-blocking mode */
termio.c_cc[VTIME] = 1; /* .1 sec timeout */
ioctl(fd, TCSETA, &termio);
return (fd);
}
/********************************
* CONVERT raw joystick data
*******************************/
void ProcessData(char* data, joystick* joy)
{
/* Data format as follows:
BITS
BYTE -7---6--5--4--3--2--1--0- DESCRIPTION
0 X11 X10 X9 X8 X7 X6 X5 X4 X-axis most significant bits
1 Y11 Y10 Y9 Y8 Y7 Y6 Y5 Y4 Y-axis most significant bits
2 Z11 Z10 Z9 Z8 Z7 Z6 Z5 Z4 Z-axis most significant bits
3 T11 T10 T9 T8 T7 T6 T5 T4 T-axis most significant bits
4 X3 X2 X1 X0 Y3 Y2 Y1 Y0 X-axis LSB, Y-axis LSB
5 Z3 Z2 Z1 Z0 T3 T2 T1 T0 Z-axis LSB, T-axis LSB
6 B7 B6 B5 B4 B3 B2 B1 B0 buttons
7 -- -- -- CH H3 H2 H1 H0 CH=switch (digital only) / hat
*/
/* upper 8 bits are combined with lower 4 bits to get a 12-bit value */
joy->x = (data[0] << 4) | ((data[4]&0xF0) >> 4);
joy->y = (data[1] << 4) | (data[4]&0x0F);
joy->z = (data[2] << 4) | ((data[5]&0xF0) >> 4);
joy->t = (data[3] << 4) | (data[5]&0x0F);
joy->buttons = data[6];
/* lower 4 bits only - hat - digital mode only */
joy->hat = data[7]&0x0F;
/* switch on Sidewinder3D Pro - digital mode only */
joy->sw = (data[7]>>4) & 01;
}
/********************************
* OUTPUT bits as binary
*******************************/
void output_binary(char x)
{
int b;
for (b=7; b>=0; b--) {
printf("%1d", ((x>>b) &01));
}
printf(" ");
}
/********************************
* OUTPUT joystick data
*******************************/
void PrintJoy(joystick* joy)
{
int i;
printf("x:%4u y:%4u z:%4u t:%4u hat:%2u sw:%1u but:",
joy->x, joy->y, joy->z, joy->t, joy->hat, joy->sw);
output_binary(joy->buttons);
}
/********************************
* MAIN program loop
*******************************/
main(int argc, char **argv)
{
int i,n;
char checksum;
joystick joy1;
joystick joy2;
printf("Opening serial port: %s. \n", serial_port);
open_port();
n=write(fd,"p",1);
printf("Polled mode\n");
if (n<1) {
printf("ERROR: write returned %d\n", n);
exit(1);
}
/* Buffer is cleared because by UNWINDER wakes up in continous mode */
printf("Clearing buffer: [");
do {
n=read(fd,buffer,1);
printf("%s",buffer);
} while (n>0);
printf("]\n");
/* You need a minimum 20 millisecond delay between each command sent */
sleep(1);
write(fd,"A",1); /* use 'a' for analog mode */
printf("joystick 1 - Digital Mode\n");
sleep(1);
write(fd,"b",1); /* use 'B' for digital mode */
printf("joystick 2 - Analog Mode\n");
sleep(1);
write(fd,"X",1);
printf("on-change mode OFF\n");
sleep(1);
write(fd,"n",1);
printf("debug mode OFF\n");
sleep(1);
write(fd,"v",1); /* output UNWINDER version */
do {
n=read(fd,buffer,1);
printf("%s",buffer);
} while (n>0);
/* SETUP POLLING MODE block for the length of the packet */
ioctl(fd, TCGETA, &termio );
termio.c_cc[VMIN] = num_bytes; /* set number of characters in packet */
termio.c_cc[VTIME] = 0; /* set to blocking mode */
ioctl(fd, TCSETA, &termio);
printf("\nSerial port blocking for %d characters\n\n",num_bytes);
/* INFINITE LOOP */
while (1) {
n=write(fd,poll_cmd,1); /* poll UNWINDER */
if (n<1) {
printf("Error sending poll command - write returned %d\n",n);
exit(1);
}
n=read(fd,in,num_bytes); /* read data from UNWINDER */
if (n!=num_bytes) {
printf("Error reading data - read returned %d\n", n); }
else {
printf("status ");
output_binary(in[0]);
printf("mode ");
output_binary(in[1]);
ProcessData(in+2, &joy1); /* process data starting at byte 3 */
PrintJoy(&joy1);
ProcessData(in+10,&joy2); /* process data starting at byte 11 */
PrintJoy(&joy2);
checksum=0; /* calculate checksum */
for(i = 0; i < (num_bytes-1); i++) { checksum = checksum+in[i]; }
if (checksum==in[i]) { printf("%3d OK\n",checksum); } else {
printf("%3d ERROR CHECKSUM=%3d\n",in[i],checksum);
}
}
}
}